package ca.ubc.cpsc210.waldo.translink;

import java.io.Reader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ca.ubc.cpsc210.waldo.exceptions.IllegalBusStopException;
import ca.ubc.cpsc210.waldo.model.BusRoute;
import ca.ubc.cpsc210.waldo.model.BusStop;
import ca.ubc.cpsc210.waldo.util.LatLon;

/**
 * A wrapper for Translink information
 * 
 * @author CPSC210 Instructor
 */

public abstract class TranslinkService {

	// Routes
	private Set<BusRoute> routes;

	// Stops
	private Set<BusStop> stops;

	/**
	 * Constructor
	 */
	public TranslinkService() {
		// Initialize the routes and stops
		routes = new HashSet<BusRoute>();
		stops = new HashSet<BusStop>();
	}

	/**
	 * Get data from Translink about stops around a given location
	 * 
	 * @param location
	 *            The latitude and longitude of the location of interest
	 * @param radius
	 *            How far from location to look for stops
	 * @param input
	 *            Where to get the Translink data from
	 */
	public abstract void getBusStopsAround(LatLon location, int radius,
			Reader input);

	/**
	 * Get data from Translink about when buses are going to arrive at a given
	 * stop
	 * 
	 * @param stop
	 *            The stop of interest
	 * @param input
	 *            Where to get the Translink data from
	 */
	public abstract void getBusEstimtesForStop(BusStop stop, Reader input);

	/**
	 * Remember a bus stop
	 * 
	 * @param stop
	 *            The stop to remember
	 */
	public void addBusStop(BusStop stop) {
		if (stop == null)
			throw new IllegalBusStopException();
		stops.add(stop);
	}

	/**
	 * Find a route
	 * 
	 * @param number
	 *            The number of the route
	 * @return The route
	 */
	public BusRoute lookupRoute(String number) {
		for (BusRoute r : routes)
			if (r.getRouteNumber().equals(number))
				return r;
		return null;
	}

	/**
	 * Return all the bus stops
	 * 
	 * @return A set of all bus stops
	 */
	public Set<BusStop> getBusStops() {
		return stops;
	}

	/**
	 * Remember the given routes
	 * 
	 * @param routes
	 *            Some routes to remember
	 */
	public void addToRoutes(List<BusRoute> routes) {
		if (routes != null)
			this.routes.addAll(routes);
	}

	/**
	 * Take a list of routes as strings and remember them as BusRoute objects
	 * 
	 * @param routesAsParsed
	 *            The routes separated by commas
	 * @return A set of BusRoute objects
	 */
	public Set<BusRoute> translateRoutes(List<String> routesAsParsed) {
		Set<BusRoute> routes = new HashSet<BusRoute>();

		if (routesAsParsed != null) {
			for (String routeNumberAsString : routesAsParsed) {
				BusRoute r = lookupRoute(routeNumberAsString);
				if (r != null)
					routes.add(r);
				else {
					r = new BusRoute(routeNumberAsString);
					routes.add(r);
				}
			}
		}
		return routes;
	}

}
